#ifndef SIGNALTHREAD_H
#define SIGNALTHREAD_H

#include <queue>
#include <stdio.h>
#include <afxwin.h>

#include "Message.h"
#include "MessageHander.h"
#include "MessageList.h"

using namespace std;

struct MessageData{
	MessageHander* pHander;
	Message* pMessage;
};

class SignalThread {
public:
	SignalThread(){
		InitializeSRWLock(&g_lock);
		InitializeConditionVariable(&g_ConditionVar);
	}
	virtual ~SignalThread(){

	}
	void start(){
		AcquireSRWLockExclusive(&g_lock);
		AfxBeginThread(run, (LPVOID)this);
		SleepConditionVariableSRW(&g_ConditionVar, &g_lock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
		ReleaseSRWLockExclusive(&g_lock);
	}
	void stop(){
		postMessage(0, 0);
	}
	int postMessage(MessageHander* hander, Message* message = 0){

		MessageData * pessageData = new MessageData();
		pessageData->pHander = hander;
		pessageData->pMessage = message;

		m_queue.push_back(pessageData);
		return 0;
	}

	int msgqueueSize(){
		return m_queue.size();
	}

private:
	void* _start(void * arg){

		while (1){

			AcquireSRWLockExclusive(&g_lock);
			WakeConditionVariable(&g_ConditionVar);
			ReleaseSRWLockExclusive(&g_lock);

			MessageData* hander = m_queue.wait();;
			if (hander->pHander){
				hander->pHander->OnMessage(hander->pMessage);
			}else{
				break;
			}
		}
		return 0;
	}

	static UINT run(void* pths){

		SignalThread* PTHIS = (SignalThread*)pths;
		PTHIS->_start(pths);
		return 0;
	}

private:

	MessageList<MessageData*> m_queue;
	SRWLOCK g_lock;
	CONDITION_VARIABLE g_ConditionVar;
};

#endif /* SIGNALTHREAD_H */